package com.bocloud.cmp.server.controller.app.resource;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.entity.app.resource.Application;
import com.bocloud.cmp.interfaces.app.resource.ApplicationService;
import com.bocloud.cmp.server.interceptor.Log;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.RequestUser;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.JSONTools;
import com.bocloud.common.utils.ResultTools;

/**
 * 
 * @author zjm
 * @date 2017年3月17日
 */
@RestController
@RequestMapping("/application")
public class ApplicationController {
	@Autowired
	private ApplicationService applicationService;

	@RequestMapping(value = "/create", method = { RequestMethod.POST })
	@Log(name = "应用创建")
	public BsmResult create(@RequestParam(value = Common.PARAMS, required = true) String params,
			@Value(Common.REQ_USER) RequestUser user) {
		JSONObject object = JSONTools.isJSONObj(params);
		if (null != object) {
			Application application = JSONObject.parseObject(object.toJSONString(), Application.class);
			return applicationService.create(user, application);
		} else {
			return ResultTools.formatErrResult();
		}
	}

	@RequestMapping(value = "/list", method = { RequestMethod.POST })
	@Log(name = "应用列表查询")
	public BsmResult list(@RequestParam(value = Common.PAGE, required = false) Integer page,
			@RequestParam(value = Common.ROWS, required = false) Integer rows,
			@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = Common.SORTER, required = false) String sorter,
			@RequestParam(value = Common.SIMPLE, required = false) boolean simple,
			@Value(Common.REQ_USER) RequestUser user) {
		List<Param> paramList = JSONObject.parseArray(params, Param.class);
		@SuppressWarnings("unchecked")
		Map<String, String> sorterMap = JSONObject.parseObject(sorter, HashMap.class);
		return applicationService.list(page, rows, paramList, sorterMap, simple, user);
	}

	@RequestMapping(value = "/listByLayout", method = { RequestMethod.POST })
	@Log(name = "编排应用列表查询")
	public BsmResult listByLayout(@RequestParam(value = Common.PAGE, required = false) Integer page,
			@RequestParam(value = Common.ROWS, required = false) Integer rows,
			@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = Common.SORTER, required = false) String sorter,
			@RequestParam(value = Common.SIMPLE, required = false) boolean simple,
			@Value(Common.REQ_USER) RequestUser user) {
		List<Param> paramList = JSONObject.parseArray(params, Param.class);
		@SuppressWarnings("unchecked")
		Map<String, String> sorterMap = JSONObject.parseObject(sorter, HashMap.class);
		return applicationService.listByLayout(page, rows, paramList, sorterMap, simple, user);
	}

	@RequestMapping(value = "/{id}/modify", method = { RequestMethod.POST })
	@Log(name = "应用信息修改")
	public BsmResult modify(@RequestParam(value = Common.PARAMS, required = true) String params,
			@Value(Common.REQ_USER) RequestUser user) {
		JSONObject object = JSONTools.isJSONObj(params);
		if (null != object) {
			Application application = JSONObject.parseObject(object.toJSONString(), Application.class);
			return applicationService.modify(application, user.getId());
		} else {
			return ResultTools.formatErrResult();
		}
	}

	@RequestMapping(value = "/{id}/detail", method = { RequestMethod.GET })
	@Log(name = "应用详情")
	public BsmResult detail(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_USER) RequestUser user) {
		return applicationService.detail(id, user);
	}

	@RequestMapping(value = "/remove", method = { RequestMethod.POST })
	@Log(name = "删除应用")
	public BsmResult remove(@RequestParam(value = Common.PARAMS, required = true) String params,
			@Value(Common.REQ_USER) RequestUser user) {
		JSONObject jsonObject = JSONTools.isJSONObj(params);
		List<Long> ids = JSON.parseArray(jsonObject.get("ids").toString(), Long.class);
		return applicationService.remove(ids, user.getId());
	}

	@RequestMapping(value = "/layoutDeploy", method = { RequestMethod.POST })
	@Log(name = "编排部署")
	public BsmResult deployApplication(@RequestParam(value = Common.PARAMS, required = true) String params,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "layoutId", required = true) Long layoutId,
			@RequestParam(value = "clusterId", required = true) Long clusterId,
			@Value(Common.REQ_USER) RequestUser user) {
		return applicationService.layoutDeploy(appId, layoutId, clusterId, user);
	}

	@RequestMapping(value = "/deleteLayoutDeploy", method = { RequestMethod.POST })
	@Log(name = "删除编排部署")
	public BsmResult deleteLayoutDeploy(@RequestParam(value = Common.PARAMS, required = true) String params,
			@Value(Common.REQ_USER) RequestUser user) {
		JSONObject jsonObject = JSONTools.isJSONObj(params);
		return applicationService.deleteLayoutDeploy(Long.parseLong(jsonObject.get("appId").toString()),
				Long.parseLong(jsonObject.get("layoutId").toString()), user);
	}

	@RequestMapping(value = "/scaleRc", method = { RequestMethod.POST })
	@Log(name = "实例变更")
	public BsmResult scaleRc(@RequestParam(value = Common.PARAMS, required = true) String params,
			@Value(Common.REQ_USER) RequestUser user) {
		JSONObject jsonObject = JSONTools.isJSONObj(params);
		return applicationService.scaleRc(Long.parseLong(jsonObject.get("appId").toString()),
				jsonObject.get("namespace").toString(), jsonObject.get("name").toString(),
				Integer.parseInt(jsonObject.get("count").toString()), user);
	}

	@RequestMapping(value = "/getPodStatus", method = { RequestMethod.POST })
	@Log(name = "查看运行实例的状态")
	public BsmResult getPodStatus(@RequestParam(value = Common.PARAMS, required = true) String params,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "namespace", required = true) String namespace,
			@RequestParam(value = "name", required = true) String name, @Value(Common.REQ_USER) RequestUser user) {
		return applicationService.getPodStatus(appId, namespace, name, user);
	}

	@RequestMapping(value = "/rolling", method = { RequestMethod.POST })
	@Log(name = "滚动升级")
	public BsmResult rolling(@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = "softwareId", required = true) Long softwareId,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "namespace", required = true) String namespace,
			@RequestParam(value = "resourceName", required = true) String resourceName,
			@Value(Common.REQ_USER) RequestUser user) {
		return applicationService.rolling(namespace, resourceName, appId, softwareId, user);
	}

	@RequestMapping(value = "/rollback", method = { RequestMethod.POST })
	@Log(name = "回滚")
	public BsmResult rollback(@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "namespace", required = true) String namespace,
			@RequestParam(value = "resourceName", required = true) String resourceName,
			@Value(Common.REQ_USER) RequestUser user) {
		return applicationService.rolling(namespace, resourceName, appId, null, user);
	}

	@RequestMapping(value = "/autoScale", method = { RequestMethod.POST })
	@Log(name = "弹性伸缩")
	public BsmResult autoScale(@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "namespace", required = true) String namespace,
			@RequestParam(value = "resourceName", required = true) String resourceName,
			@RequestParam(value = "requestValue", required = true) String requestValue,
			@RequestParam(value = "minReplicas", required = true) Integer minReplicas,
			@RequestParam(value = "maxReplicas", required = true) Integer maxReplicas,
			@RequestParam(value = "cpuTargetUtilization", required = true) Integer cpuTargetUtilization,
			@Value(Common.REQ_USER) RequestUser user) {
		return applicationService.autoScale(appId, namespace, resourceName, requestValue, minReplicas, maxReplicas,
				cpuTargetUtilization, user);
	}

	@RequestMapping(value = "/editRcResource", method = { RequestMethod.POST })
	@Log(name = "设置资源限制")
	public BsmResult editRcResource(@RequestParam(value = Common.PARAMS, required = false) String params,
			@Value(Common.REQ_USER) RequestUser user) {
		JSONObject jsonObject = JSONTools.isJSONObj(params);
		@SuppressWarnings("unchecked")
		Map<String, String> limits = JSON.parseObject(jsonObject.get("limits").toString(), HashMap.class);
		@SuppressWarnings("unchecked")
		Map<String, String> requests = JSON.parseObject(jsonObject.get("requests").toString(), HashMap.class);
		return applicationService.editRcResource(Long.parseLong(jsonObject.get("appId").toString()),
				jsonObject.get("namespace").toString(), jsonObject.get("rcName").toString(), limits, requests, user);
	}

	@RequestMapping(value = "/getPodResource", method = { RequestMethod.POST })
	@Log(name = "查看运行实例资源")
	public BsmResult getPodResource(@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "namespace", required = true) String namespace,
			@RequestParam(value = "resourceName", required = true) String resourceName,
			@RequestParam(value = "resourceType", required = true) String resourceType,
			@Value(Common.REQ_USER) RequestUser user) {
		if (StringUtils.isBlank(resourceName) || StringUtils.isBlank(resourceType)) {
			return ResultTools.formatErrResult();
		}
		return applicationService.getPodResource(appId, namespace, resourceName, resourceType, user);
	}

	@RequestMapping(value = "/getHPA", method = { RequestMethod.POST })
	@Log(name = "弹性伸缩列表展示")
	public BsmResult getHPA(@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "namespace", required = true) String namespace,
			@RequestParam(value = "resourceName", required = true) String resourceName,
			@RequestParam(value = "resourceType", required = true) String resourceType,
			@Value(Common.REQ_USER) RequestUser user) {
		if (StringUtils.isBlank(resourceName) || StringUtils.isBlank(resourceType)) {
			return ResultTools.formatErrResult();
		}
		return applicationService.getHPA(appId, namespace, resourceName, resourceType, user);
	}

	@RequestMapping(value = "/deleteResource", method = { RequestMethod.POST })
	@Log(name = "删除资源")
	public BsmResult deleteResource(@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "namespace", required = true) String namespace,
			@RequestParam(value = "resourceName", required = true) String resourceName,
			@RequestParam(value = "resourceType", required = true) String resourceType,
			@Value(Common.REQ_USER) RequestUser user) {
		if (StringUtils.isBlank(resourceName) || StringUtils.isBlank(resourceType)) {
			return ResultTools.formatErrResult();
		}
		return applicationService.deleteResource(appId, namespace, resourceName, resourceType, user);
	}

	@RequestMapping(value = "/getReplicas", method = { RequestMethod.POST })
	@Log(name = "获取实例数")
	public BsmResult getReplicas(@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "namespace", required = true) String namespace,
			@RequestParam(value = "resourceName", required = true) String resourceName,
			@RequestParam(value = "resourceType", required = true) String resourceType,
			@Value(Common.REQ_USER) RequestUser user) {
		if (StringUtils.isBlank(resourceName) || StringUtils.isBlank(resourceType)) {
			return ResultTools.formatErrResult();
		}
		return applicationService.getReplicas(appId, namespace, resourceName, resourceType, user);
	}
	
	@RequestMapping(value = "/rebuildServices", method = { RequestMethod.POST })
	@Log(name = "重建服务")
	public BsmResult rebuildServices(@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "namespace", required = true) String namespace,
			@RequestParam(value = "resourceName", required = true) String resourceName,
			@Value(Common.REQ_USER) RequestUser user) {
		return applicationService.rebuildServices(namespace, resourceName, appId, null, user);
	}

	@RequestMapping(value = "/upgrade", method = { RequestMethod.POST })
	@Log(name = "全量升级")
	public BsmResult upgrade(@RequestParam(value = Common.PARAMS, required = false) String params,
			@RequestParam(value = "softwareId", required = true) Long softwareId,
			@RequestParam(value = "appId", required = true) Long appId,
			@RequestParam(value = "namespace", required = true) String namespace,
			@RequestParam(value = "resourceName", required = true) String resourceName,
			@Value(Common.REQ_USER) RequestUser user) {
		return applicationService.upgrade(namespace, resourceName, appId, softwareId, user);
	}

}
